package com.wangziyu.facerecognitiongate.printer

import java.nio.charset.Charset


/**
 * @description [收银小票打印工具，支持多列、多行自动换行、对齐方式]
 * @author wzy
 * @date 2025/09/04 23:44:00
 */
class ReceiptPrinter(
    private val lineWidth: Int,                // 整行宽度（字符数，58mm常用32，80mm常用48）
    private val columnWidths: List<Int>,       // 每列宽度
    private val aligns: List<Align>            // 每列对齐方式
) {
    enum class Align { LEFT, RIGHT, CENTER }

    // 缓存 GBK Charset，避免每次都创建
    private val gbk: Charset = try {
        Charset.forName("GBK")
    } catch (e: Exception) {
        // 如果设备不支持 GBK，可以回退到 UTF-8（但宽度计算会不同）
        Charset.forName("UTF-8")
    }

    // 计算中英文混排的实际宽度（以打印机字符宽度为准，汉字通常算2）
    private fun getStringWidth(text: String): Int = text.toByteArray(gbk).size

    /**
     * 按列宽切分字符串（按字节宽度切）
     */
    private fun wrapText(text: String, colWidth: Int): List<String> {
        val result = mutableListOf<String>()
        if (text.isEmpty()) {
            result.add("")
            return result
        }

        var cur = StringBuilder()
        var curWidth = 0

        for (ch in text) {
            // 以单字符转为 GBK bytes 计算其占用的字节数（中文一般 2，英文 1）
            val chWidth = ch.toString().toByteArray(gbk).size
            if (curWidth + chWidth > colWidth) {
                result.add(cur.toString())
                cur = StringBuilder()
                curWidth = 0
            }
            cur.append(ch)
            curWidth += chWidth
        }
        if (cur.isNotEmpty()) result.add(cur.toString())
        return result
    }

    // 按对齐方式填充空格（空格按 1 字节）
    private fun formatText(text: String, width: Int, align: Align): String {
        val len = getStringWidth(text)
        val space = if (len < width) width - len else 0
        return when (align) {
            Align.LEFT -> text + " ".repeat(space)
            Align.RIGHT -> " ".repeat(space) + text
            Align.CENTER -> {
                val left = space / 2
                val right = space - left
                " ".repeat(left) + text + " ".repeat(right)
            }
        }
    }

    /**
     * 生成一行或多行小票文本
     * @param values 每列的内容（长度必须与 columnWidths 与 aligns 一致）
     */
    fun formatRow(values: List<String>): String {
        if (values.size != columnWidths.size || values.size != aligns.size) {
            throw IllegalArgumentException("values, columnWidths and aligns must have the same length")
        }

        val wrappedCols = values.mapIndexed { index, value ->
            wrapText(value, columnWidths[index])
        }

        val maxLines = wrappedCols.maxOf { it.size }
        val sb = StringBuilder()

        for (i in 0 until maxLines) {
            for (j in values.indices) {
                val text = if (i < wrappedCols[j].size) wrappedCols[j][i] else ""
                sb.append(formatText(text, columnWidths[j], aligns[j]))
            }
            sb.append("\n")
        }
        return sb.toString()
    }

    fun divider(char: Char = '-'): String {
        return char.toString().repeat(lineWidth) + "\n"
    }
}